package com.kuangstudy.service.login;

import com.alibaba.fastjson.JSON;
import com.kuangstudy.entity.LoginUser;
import com.kuangstudy.entity.User;
import com.kuangstudy.utils.jwt.JwtUtil;
import com.kuangstudy.utils.redis.RedisCache;
import com.kuangstudy.utils.result.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * Description:
 * Author: ryt
 * Version: 1.0
 * Create Date Time: 2021/12/22 9:48.
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService{

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    // 登陆方法
    @Override
    public ResponseResult login(User user) {
        // 1、通过AuthenticationManager的authenticate方法来进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(user.getUserName(),user.getPassword());
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        log.info("{}",authentication);
        // 2、如果认证失败，给出相应的提示
        if (StringUtils.isEmpty(authentication)){
            throw new RuntimeException("登陆失败");
        }

        // 3、认证通过了，使用userid生成一个jwt，使用R类进行返回
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String jwtByuserId = JwtUtil.createJWT(userId);
        Map<String,String> map = new HashMap<>();
        map.put("token",jwtByuserId);

        // 4、把完整的信息存入到redis中，减小数据库的压力
        redisCache.setCacheObject("login:"+userId,loginUser);

        // 5、返回
        return new ResponseResult(200,"success",map);
    }

    @Override
    public ResponseResult logout() {
        // 因为一个请求先进来先进入到 JwtAuthenticationTokenFilter中，
        // 将用户信息封装成Authentication 并存入到SecurityContextHolder中，在进行放行
        // 并且是同一个请求，所以 authentication 值是一样的！
        // 1、获取SecurityContextHolder中的用户的useid
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long userId = loginUser.getUser().getId();
        String rediskey = "login:" + userId;

        // 2、删除redis中储存的值
        redisCache.deleteObject(rediskey);
        return new ResponseResult(200,"注销成功");
    }

}
